/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.web.util;

import org.vacoor.nothing.common.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author vacoor
 */
public abstract class WebUtils {
    public static final String FIRST_IP_PATTERN = "^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9]))(?:(?:\\s*,\\s*)?)";
    public static final Pattern PATTERN = Pattern.compile(FIRST_IP_PATTERN);

    public static boolean isAsyncRequest(HttpServletRequest request) {
        return ("XMLHttpRequest".equals(request.getHeader("X-Requested-With")));
    }

    public static String urlAppend(String url, String text) {
        if (!StringUtils.hasLength(text)) {
            return url;
        }
        return url + (-1 == url.indexOf('?') ? '?' : '&') + text;
    }

    /**
     * Retrieves the current request servlet path.
     * Deals with differences between servlet specs (2.2 vs 2.3+)
     *
     * @param request the request
     * @return the servlet path
     */
    public static String getServletPath(HttpServletRequest request) {
        String servletPath = request.getServletPath();
        String requestUri = request.getRequestURI();

        // Detecting other characters that the servlet container cut off (like anything after ';')
        if (requestUri != null && servletPath != null && !requestUri.endsWith(servletPath)) {
            int pos = requestUri.indexOf(servletPath);
            if (pos > -1) {
                servletPath = requestUri.substring(requestUri.indexOf(servletPath));
            }
        }

        if (null != servletPath && !"".equals(servletPath)) {
            return servletPath;
        }

        int startIndex = "".equals(request.getContextPath()) ? 0 : request.getContextPath().length();
        int endIndex = request.getPathInfo() == null ? requestUri.length() : requestUri.lastIndexOf(request.getPathInfo());

        if (startIndex > endIndex) { // this should not happen
            endIndex = startIndex;
        }

        return requestUri.substring(startIndex, endIndex);
    }

    // 获取用户真实IP
    public static String getRemoteIPAddress(HttpServletRequest request) {
        // 一些投票系统使用该 Header来限制用户投票,伪造后限制就失效
        String ip = request.getHeader("X-Forwarded-For");

        // 如果经过代理, 获取用户IP 或 第一个非高匿代理服务器IP
        if (ip != null) {
            // XFF 等 HTTP 头 可伪造, 进行过滤, 防止SQL注入
            Matcher matcher = PATTERN.matcher(ip);
            if (matcher.find()) {
                return matcher.group(1);
            }
        }

        /* 下面这些不懂暂时不加
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }

        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        */

        // 没有经过代理 或 代理信息不安全则使用 remoteAddr
        return request.getRemoteAddr();
    }

    private WebUtils() {
    }
}
